package com.tsd.jxc.buy.service.impl;

import com.tsd.common.vo.BatchDeleteLogicVo;
import com.tsd.core.thread.ThreadPoolTaskUtil;
import com.tsd.core.utils.DoubleUtil;
import com.tsd.core.utils.HlpUtils;
import com.tsd.core.utils.ListUtil;
import com.tsd.core.vo.HlpException;
import com.tsd.core.vo.PageBean;
import com.tsd.jxc.buy.dao.JxcBuyOrderDetailMapper;
import com.tsd.jxc.buy.dao.JxcBuyReturnBillDetailMapper;
import com.tsd.jxc.buy.dao.JxcBuyReturnBillMapper;
import com.tsd.jxc.buy.entity.JxcBuyReturnBillDetail;
import com.tsd.jxc.buy.entity.JxcBuyReturnBillDetailExt;
import com.tsd.jxc.buy.entity.JxcBuyReturnBillExt;
import com.tsd.jxc.buy.service.JxcBuyReturnBillDetailService;
import com.tsd.jxc.goods.entity.JxcGoodsPriceExt;
import com.tsd.jxc.goods.service.JxcGoodsPriceService;
import com.tsd.jxc.stock.StockConstants;
import com.tsd.service.BaseServiceImpl;
import com.tsd.system.entity.SysUser;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * 描述：JxcBuyReturnBillDetail 服务实现层
 *
 * @author Hillpool
 * @date 2022/07/29 15:00:45
 */
@Service
public class JxcBuyReturnBillDetailServiceImpl extends BaseServiceImpl implements JxcBuyReturnBillDetailService {

    @Resource
    private JxcBuyReturnBillDetailMapper jxcBuyReturnBillDetailMapper;
    @Resource
    private JxcBuyReturnBillMapper jxcBuyReturnBillMapper;
    @Resource
    private JxcBuyOrderDetailMapper jxcBuyOrderDetailMapper;
    @Resource
    private JxcGoodsPriceService jxcGoodsPriceService;

    @Override
    public JxcBuyReturnBillDetail getJxcBuyReturnBillDetailById(Long id) throws Exception {
        return jxcBuyReturnBillDetailMapper.selectByPrimaryKey(id);
    }

    @Override
    public JxcBuyReturnBillDetailExt queryBySid(String sid) throws Exception {
        return jxcBuyReturnBillDetailMapper.selectBySid(sid);
    }

    @Override
    public List<JxcBuyReturnBillDetailExt> queryValidByReturnList(List<String> return_list) {
        List<JxcBuyReturnBillDetailExt> detailExtList = ThreadPoolTaskUtil.queryInList4Split(return_list, list -> {
            JxcBuyReturnBillDetailExt params = new JxcBuyReturnBillDetailExt();
            params.setDr(0);
            params.setReturn_list(list);
            return jxcBuyReturnBillDetailMapper.selectByEntity(params);
        });
        if (!HlpUtils.isEmptyList(detailExtList)) {
            List<String> goodsList = ListUtil.map(detailExtList, JxcBuyReturnBillDetailExt::getGoods_sid);
            List<JxcGoodsPriceExt> priceExtList = jxcGoodsPriceService.queryByGoodsList(goodsList);
            for (JxcBuyReturnBillDetailExt detailExt : detailExtList) {
                List<JxcGoodsPriceExt> filters = ListUtil.filter(priceExtList, t -> t.getGoods_sid().equals(detailExt.getGoods_sid()));
                detailExt.setPrice_list(filters);
                detailExt.calcGoodsPrice();
            }
        }
        return detailExtList;
    }

    @Override
    public void deleteJxcBuyReturnBillDetails(List<String> list, SysUser opUser) throws Exception {
        for (String sid : list) {
            JxcBuyReturnBillDetail old = jxcBuyReturnBillDetailMapper.selectBySid(sid);
            super.checkEmpty(old, "该记录不存在");
            super.autoInjectBaseData(old, opUser, TYPE_DELETE);
            jxcBuyReturnBillDetailMapper.updateByPrimaryKeySelective(old);
        }
    }

    @Override
    public void saveJxcBuyReturnBillDetail(JxcBuyReturnBillDetail record, SysUser opUser) throws Exception {
        if (HlpUtils.isEmpty(record.getId())) {
            super.autoInjectBaseData(record, opUser, this.TYPE_CREATE);
            jxcBuyReturnBillDetailMapper.insertSelective(record);
        } else {
            super.autoInjectBaseData(record, opUser, this.TYPE_UPDATE);
            jxcBuyReturnBillDetailMapper.updateByPrimaryKeySelective(record);
        }
    }

    @Override
    public void saveJxcBuyReturnBillDetail(JxcBuyReturnBillExt record, SysUser opUser) throws Exception {
        List<JxcBuyReturnBillDetailExt> detailExtList = record.getDetail_list();
        super.checkEmptyList(detailExtList, "退货明细不能为空");

        List<Long> existIdList = ListUtil.filterMap(detailExtList, t -> !HlpUtils.isEmpty(t.getId()), JxcBuyReturnBillDetailExt::getId);

        List<JxcBuyReturnBillDetailExt> oldList = this.queryValidByReturnList(Collections.singletonList(record.getSid()));

        //删除不存在的退货明细
        List<JxcBuyReturnBillDetailExt> delList = ListUtil.filter(oldList, t -> !existIdList.contains(t.getId()));
        if (!HlpUtils.isEmptyList(delList)) {
            List<Long> delIds = ListUtil.map(delList, JxcBuyReturnBillDetailExt::getId);
            BatchDeleteLogicVo logicVo = new BatchDeleteLogicVo(opUser);
            logicVo.setIdList(delIds);
            jxcBuyReturnBillDetailMapper.deleteLogicByIdList(logicVo);
        }

        List<JxcBuyReturnBillDetailExt> insertList = new ArrayList<>();
        List<JxcBuyReturnBillDetailExt> updateList = new ArrayList<>();
        double totalQty = 0D, totalAmount = 0D;
        for (JxcBuyReturnBillDetailExt detailExt : detailExtList) {
            if (HlpUtils.isEmpty(detailExt.getOut_bill())) {
                detailExt.setOut_bill(StockConstants.DETAIL_IN_OUT_BILL_NONE);
            }
            super.checkEmpty(detailExt.getQty(), "第" + detailExt.getSn() + "项明细数量不能为空");
            super.checkEmpty(detailExt.getPrice(), "第" + detailExt.getSn() + "项明细单价不能为空");
            detailExt.setReturn_sid(record.getSid());
            if (HlpUtils.isAllNotEmpty(detailExt.getQty(), detailExt.getUnit_qty())) {
                detailExt.setQty4base(BigDecimal.valueOf(DoubleUtil.mul(detailExt.getQty(), detailExt.getUnit_qty())));
            }
            if (HlpUtils.isEmpty(detailExt.getAmount())) {
                double amount = DoubleUtil.mul(detailExt.getQty(), detailExt.getPrice());
                detailExt.setAmount(BigDecimal.valueOf(amount));
            }
            totalQty = DoubleUtil.add(totalQty, detailExt.getQty());
            totalAmount = DoubleUtil.add(totalAmount, detailExt.getAmount());
            if (HlpUtils.isEmpty(detailExt.getId())) {
                super.autoInjectBaseData(detailExt, opUser, this.TYPE_CREATE);
                insertList.add(detailExt);
            } else {
                super.autoInjectBaseData(detailExt, opUser, this.TYPE_UPDATE);
                updateList.add(detailExt);
            }
        }
        if (!HlpUtils.isEmptyList(insertList)) {
            ThreadPoolTaskUtil.executeInList4Split(insertList, false, items -> jxcBuyReturnBillDetailMapper.insertList(items));
        }
        if (!HlpUtils.isEmptyList(updateList)) {
            ThreadPoolTaskUtil.executeInList4Split(updateList, false, 1, items -> jxcBuyReturnBillDetailMapper.updateByPrimaryKeySelective(items.get(0)));
        }

        record.setQty(BigDecimal.valueOf(totalQty));
        record.setAmount(BigDecimal.valueOf(totalAmount));
        if (!HlpUtils.isEmpty(record.getFree_shipping()) && record.getFree_shipping() == 1) {
            record.setTotal_amount(record.getAmount());
        } else {
            double value = DoubleUtil.add(totalAmount, record.getReal_freight());
            record.setTotal_amount(BigDecimal.valueOf(value));
        }

        double shouldReturnAmount = record.getTotal_amount().doubleValue();
        if (!HlpUtils.isEmpty(record.getIgnore_amount())) {
            shouldReturnAmount = DoubleUtil.sub(shouldReturnAmount, record.getIgnore_amount());
        }
        record.setShould_return_amount(BigDecimal.valueOf(shouldReturnAmount));

        double unReturnAmount = record.getShould_return_amount().doubleValue();
        if (!HlpUtils.isEmpty(record.getReturn_amount())) {
            unReturnAmount = DoubleUtil.sub(unReturnAmount, record.getReturn_amount());
        }
        if (unReturnAmount < 0) {
            throw new HlpException("已退金额不能大于应退金额");
        }
        record.setUn_return_amount(BigDecimal.valueOf(unReturnAmount));
        jxcBuyReturnBillMapper.updateByPrimaryKeySelective(record);
    }

    @Override
    public List<JxcBuyReturnBillDetailExt> findJxcBuyReturnBillDetails(Map<String, Object> params, PageBean page) throws Exception {
        return jxcBuyReturnBillDetailMapper.selectByPage(params, page);
    }

    @Override
    public List<JxcBuyReturnBillDetailExt> findJxcBuyReturnBillDetails(Map<String, Object> params) throws Exception {
        return jxcBuyReturnBillDetailMapper.selectByParams(params);
    }

    @Override
    public void undateReturn2BuyOrder(List<String> return_bill_list) throws Exception {
        List<String> sidList = jxcBuyReturnBillDetailMapper.selectBuyDetailSidByReturnSidList(return_bill_list);
        jxcBuyOrderDetailMapper.updateReturnInfo(sidList);
        jxcBuyReturnBillMapper.updateReturnInfo(return_bill_list);
    }
}
